﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Security.Policy;
using System.Text;
using System.Threading.Tasks;
using APICommon;
using DataProvider;

namespace APIComparer
{
    public class Comparer
    {
        public static void Process(string directory, Action<Result> resultAction, Action<Progress> progressAction)
        {
            string[] files = System.IO.Directory.GetFiles(directory, "*.dll");
            List<string> assemblies = new List<string>();
            using (var db = new APIDBContext())
            {
                assemblies.AddRange(db.Methods.Select(s => s.Assembly).Distinct());
                assemblies.AddRange(db.Fields.Select(s => s.Assembly).Distinct());
                assemblies = assemblies.Distinct().ToList();
            }

            foreach (string file in files)
            {
                if (assemblies.FirstOrDefault(s => string.Compare(s, Path.GetFileName(file), true) == 0) != null)
                {
                    var result = ProcessAssemblyFile(file, progressAction);
                    if (resultAction != null)
                    {
                        resultAction(result);
                    }
                }
            }
        }

        private static Result ProcessAssemblyFile(string file, Action<Progress> progressAction)
        {
            Result result = new Result();
            try
            {
                /*
                // Create application domain setup information
                AppDomainSetup domaininfo = new AppDomainSetup();
                //Create evidence for the new appdomain from evidence of the current application domain
                Evidence adevidence = AppDomain.CurrentDomain.Evidence;

                domaininfo.ApplicationBase = AppDomain.CurrentDomain.BaseDirectory;
                domaininfo.PrivateBinPath = string.Format("{0};{1}", Path.GetDirectoryName(file), AppDomain.CurrentDomain.RelativeSearchPath);
                AppDomain myDomain = AppDomain.CreateDomain("Temporary", adevidence, domaininfo);
                */

                //AppDomain myDomain = AppDomain.CreateDomain(Guid.NewGuid().ToString());
                ////Create the loader (a proxy).
                //var assemblyLoader = (CompareAssemblyProcessor)myDomain.CreateInstanceAndUnwrap(typeof(CompareAssemblyProcessor).Assembly.FullName, typeof(CompareAssemblyProcessor).FullName);
                ////Load an assembly in the LoadFrom context. Note that the Load context will
                ////not work unless you correctly set the AppDomain base-dir and private-bin-paths.
                var assemblyLoader = new CompareAssemblyProcessor();
                result = assemblyLoader.Process(file, progressAction);
                
                //Finally unload the AppDomain.
                //AppDomain.Unload(myDomain);
            }
            catch(Exception ex)
            {
                result.HasErrors = true;
                result.Errors.Add(ex.Message);
                System.Diagnostics.Debug.WriteLine(string.Format("Exception {0}",ex.Message));
            }

            return result;
        }
    }
}
